Titre

---------------------------------------- Chapitre I - Les bases ----------------------------------------

Crackme2 - partie 2

 

Cible : CrackMe2

Outils nécessaires :
OllyDbg (by Oleh Yuschuk)

 

Cette 3eme solution est le keygenning. C'est l'art de créer un programme (keygen : KEY GEN erator, générateur de clé) permettant de calculer un serial en fonction de différentes données comme un nom par exemple. Pour cela, il faut étudier plus en profondeur le programme cible afin de trouver la méthode de calcul utilisée. Reprenons le crackme2. Revenons au départ avec CTRL+F2 (ou CTRL+F2). On relance le crackme2 avec F9 (ou F9), on rentre le couple bidon "Kirjo" / "12345", OK et on breake sur la 1ere API. Un petit F8 (ou F8) pour exécuter celle-ci et on se retrouve là :

1er break

Comme précédemment, on peut voir que le nom est récupéré puis stocké à l'adresse 403150 . L'adresse est visible soit grâce au PUSH qui indique à la fonction où écrire ce qu'elle récupère (1) soit dans la pile puisque l'adresse a été poussée dans celle-ci et qu'Olly nous indique son contenu lorsqu'il s'agit de caractères ASCII (2). Nous allons utiliser à nouveau la technique du BPM (breakpoint memory). Soit vous faites un clic droit dans le dump, puis Goto expression / 403150 soit vous faites un clic droit dans la pile sur l'adresse du name puis Follow in dump. Avant de poser un nouveau BP, on va nettoyer les existants afin de breaker uniquement où cela nous arrange. Cliquer sur ALT+Y (ou ALT+Y) :

MemoryBP window

Ici sont listés tous les memory breakpoints. On retrouve celui que l'on a posé tout à l'heure avec en 1 son adresse (et le label qui nous permet de l'identifier rapidement), en 2 le type du BP (ici R pour Read / lecture et W pour write / écriture) et en 3 son statut (Active ou Disabled / désactivé). Clic droit sur la ligne, Disable et on est tranquille (vous verrez que dans le dump notre BPM est toujours présent mais apparaît désormais en jaune). On retourne dans la fenêtre code ( ALT+C ou ALT+C). Clic droit sur la 1ere lettre du name (ou sur 4Bh), Add label, "name", encore clic droit au même endroit, Breakpoint, Memory ..., cochez Read access et Write access si ils ne le sont pas déjà, OK. On relance avec F9 (ou F9), on breake sur la 2eme API qui récupère le serial, F9 (ou F9) et on breake dans le module KERNELBASE :

KERNELBASE

Nous le voyons en haut dans la barre de titre. Nous avons breaké ici sur un accès au name (en bas à droite de la fenêtre). Pour revenir dans notre programme juste après le call qui a appelé cette fonction, nous allons utiliser Execute till return, CTRL+F9 (ou CTRL+F9). Cela va nous permettre d'exécuter le code jusqu'à la ligne suivant le prochain RET (rappelez-vous la configuration d'Olly au début de ce tutorial) sans passer par toutes les lignes avec un F8. Un seul nous suffira cette fois-ci pour revenir dans le code du crackme (surveillez la barre de titre) :

Return from Kernel

Juste au-dessus de la ligne où nous sommes revenu, il y a un appel à la fonction lstrlenA (lSTR ingLENgthA / longueur de chaîne) avec comme argument le nom. Pas besoin d'explication sur cette fonction, d'autant qu'Olly nous indique la valeur de retour et où elle est stockée (EAX ). Vu que le code commence par travailler sur le nom, il est possible que l'on soit dans la routine qui calcule le bon serial. On va donc se mettre un repère (je vous montre cette astuce car même si elle n'est pas très utile ici, elle pourra vous servir lorsque vous tracerez des codes plus compliqué que celui-ci). Au début de la 1ere ligne de la boucle (4011130), vous pouvez voir le signe $ . Cela signifie que cette ligne est appelée par un CALL. Comme on avait fait dans le dump, on va poser un label sur cette ligne. Clic droit, Add label et saisissez "CalculSerial". Une fois cela fait, mettez-vous dans la fenêtre information sur la ligne Local call from ..., clic droit et vous pouvez voir d'où est effectué l'appel :

Goto call

Si vous cliquez sur Goto call ..., vous arriverez directement sur la ligne d'appel :

Affichage CalculSerial

Cette technique permet de remonter le code en suivant les calls. D'autre part, vous pouvez voir la nouvelle écriture du call vers notre routine. Cette parenthèse refermée, traçons ligne par ligne avec F8 (ou F8) et mettons en commentaire ce que fait le code (les commentaires sont accessibles soit avec clic droit / Add comment soit avec la touche ";") :

Test du nom

Dans cette partie, il est facile de se rendre compte que le programme teste si un nom a été saisi puis vérifie si le nombre de caractères est inférieur à 20d (14 h).

XOR du nom

Ici, de la même manière que pour le serial saisi, on modifie le nom en effectuant un XOR 13h (19 d) sur chaque caractère. On arrive ensuite sur la boucle que l'on a déjà étudiée (celle qui modifie le serial saisi), on va donc la passer rapidement en posant un BP (F2) à la sortie de celle-ci sur le POP EAX :

BP sur POP EAX

F9 (ou F9) et on étudie la suite à coup de F8 (ou F8) :

Follow in dump

Pour les 2 premières lignes, pas de problème, par contre la 3eme met dans EDI une adresse mémoire. On va aller voir ce qu'elle pourrait bien contenir. Faites un clic droit sur la ligne de code, Follow in Dump / Immediate constant. Le dump se positionne à l'adresse contenue dans la ligne de code et nous pouvons voir qu'il s'agit d'un emplacement vide, sans doute l'endroit où va être stocké le résultat des prochains calculs. Continuons notre analyse :

MOV DL

Le code (1) ne présente pas de difficultés, par contre en 40119A, on récupère en mémoire une valeur que l'on charge dans DL. Pour savoir de quoi il s'agit, cliquez dans la fenêtre informations sur la ligne contenant l'adresse (2) puis clic droit / Follow in Dump (3). Le dump se positionne, on remonte d'une ligne pour une meilleure vue (4) et on voit qu'il s'agit du 5eme caractère (soit le dernier) du nom modifié (5). Continuons l'analyse avec notre amie F8 (ou F8) :

Routine serial

On passe ensuite à la comparaison du serial saisi et du serial qui vient d'être calculé. On a maintenant tous les éléments pour coder un keygen. Pour résumer :

Plus qu'à traduire cela dans votre langage préféré ...

Maintenant que vous avez acquis les bases du reversing, nous allons voir quelques exemples de comportement d'un programme à objectif commercial.

 

Precedent        Sommaire        Suivant